/////////////////////////////////////////////////////////////////////////
//
// Amuse Engine SDK - resource
// Copyright( c) 2014.  All Rights Reserved
//
// File:		AEShadersInclude.h
// Author:		Gianluca Belardelli
// Date:		12/12/2014
//
/////////////////////////////////////////////////////////////////////////
#ifndef _AESHADERSINCLUDE_H_
#define _AESHADERSINCLUDE_H_

// forward declarations
class AEShaderProgramResource;
class AEShaderConstantTable;

#if defined(AE_OPENGL) || defined(AE_OPENGLES2) || defined(AE_OPENGLES3)

class AEGPUProgramOGL;

typedef AEGPUProgramOGL AEVertexShaderObject;
typedef AEGPUProgramOGL AEPixelShaderObject;
typedef AEGPUProgramOGL AEGeometryShaderObject;

typedef AEUINT32 AEShaderProgramHandle;

#endif

typedef AESmartPtr<AEVertexShaderObject>	AEVertexShaderObjectPtr;
typedef AESmartPtr<AEPixelShaderObject>		AEPixelShaderObjectPtr;
typedef AESmartPtr<AEGeometryShaderObject>	AEGeometryShaderObjectPtr;
typedef AESmartPtr<AEShaderConstantTable>	AEShaderConstantTablePtr;

typedef AESmartPtr<AEVertexBuffer>			AEVertexBufferPtr;
typedef AESmartPtr<AEIndexBuffer>			AEIndexBufferPtr;

enum AEShaderStage
{
	AESHADERSTAGE_INVALID             =-1,
	AESHADERSTAGE_VERTEXSHADER        = 0,
	AESHADERSTAGE_PIXELSHADER         = 1,
	AESHADERSTAGE_SKINNINGSHADER      = 2,
	AESHADERSTAGE_GEOMETRYSHADER      = 3,
	AESHADERSTAGE_DOMAINSHADER        = 4,
	AESHADERSTAGE_HULLSHADER          = 5,
	AESHADERSTAGE_COMPUTESHADER       = 6,

#ifdef AE_OPENGL
	AESHADERSTAGE_MAXPLATFORMSTAGE    = 7,
#elif defined( AE_OPENGLES2 )
	AESHADERSTAGE_MAXPLATFORMSTAGE    = 3,
#endif

	AESHADERSTAGE_MAXSTAGECOUNT       = 7 
};

enum AEShaderModel
{
	SHADERMODEL_INVALID       = -1,   ///< Reserved. Represents an invalid shader model.
	SHADERMODEL_SM20          =  0,   ///< vs and ps
	SHADERMODEL_SM2a          =  1,   ///< vs and ps
	SHADERMODEL_SM2b          =  2,   ///< vs and ps
	SHADERMODEL_SM30          =  3,   ///< vs and ps
	SHADERMODEL_SM40          =  4,   ///< vs, ps and gs (DX10, DX11)
	SHADERMODEL_SM41          =  5,   ///< vs, ps and gs (DX10, DX11)
	SHADERMODEL_SM40_LEVEL_91 =  6,   ///< vs and ps (DX11 Level 9)
	SHADERMODEL_SM40_LEVEL_93 =  7,   ///< vs and ps (DX11 Level 9)
	SHADERMODEL_SM50          =  8,   ///< vs, ps, gs, hs, ds, cs (DX11)
	SHADERMODEL_COUNT         =  9
};

/// \brief
///   Enum that defines base variable types
enum AEValueType
{
	AEVALUETYPE_UNKNOWN = -1,
	AEVALUETYPE_BOOL = 0,
	AEVALUETYPE_INT,
	AEVALUETYPE_FLOAT,
	AEVALUETYPE_FLOAT2,
	AEVALUETYPE_FLOAT3,
	AEVALUETYPE_FLOAT4,
	AEVALUETYPE_FLOAT3x3,
	AEVALUETYPE_FLOAT4x4,
	AEVALUETYPE_STRING,
	AEVALUETYPE_TEXTURE,
	AEVALUETYPE_CUBEMAP,
	AEVALUETYPE_TEXTURE3D,
	AEVALUETYPE_BOOL2,
	AEVALUETYPE_BOOL3,
	AEVALUETYPE_BOOL4,
	AEVALUETYPE_INT2,
	AEVALUETYPE_INT3,
	AEVALUETYPE_INT4,
	AEVALUETYPE_UINT,
	AEVALUETYPE_TEXTURE2DARRAY,
	AEVALUETYPE_FLOAT4x3,
	AEVALUETYPE_INCLUSION_TAG
};

/// \brief
///   All available transparency type for surfaces/primitives
enum AETransparencyType 
{
	AETRANSPTYPE_NONE = 0,              ///< no transparency
	AETRANSPTYPE_MULTIPLICATIVE = 1,    ///< multiplicative transparency
	AETRANSPTYPE_ALPHA = 2,             ///< regular alpha blending
	AETRANSPTYPE_ADDITIVE = 3,          ///< additive transparency
	AETRANSPTYPE_ALPHATEST = 4,         ///< no transparency, only alpha test
	AETRANSPTYPE_ADD_MODULATE = 5,      ///< add the modulated result (dest=dest*(1+src))
	AETRANSPTYPE_ADDITIVE_NOALPHA = 6,  ///< additive transparency, ignoring source and destination alpha
	AETRANSPTYPE_NOCOLORWRITE = 7,      ///< no blend, no color write, no alpha test
	AETRANSPTYPE_MODULATE2X = 8,        ///< modulate and multiply by two
	AETRANSPTYPE_SUBTRACTIVE = 9,       ///< subtractive blending (dest-src*src.a)
	AETRANSPTYPE_PREMULTIPLIEDALPHA = 10, ///< subtractive blending (src+(dest*(1-src.a))
	AETRANSPTYPE_ALPHA_NOALPHATEST_PARTICLES = 11, ///< same as alpha without alphatest but selects special states for particles (internal use)
	AETRANSPTYPE_ALPHA_PARTICLES = 12,  ///< same as alpha but selects special states for particles (internal use)
	AETRANSPTYPE_ALPHA_NOALPHATEST = 15, ///< same as alpha, but without alpha test (internal use)
};

/// \brief
///   Enum that defines the rasterizer's face culling mode for triangles
enum AECullMode
{
	AECULLMODE_NONE		= 1,
	AECULLMODE_FRONT	= 2,
	AECULLMODE_BACK		= 3
};

/// \brief
///   Enum that defines the rasterizer's fill mode for triangles
enum AEFillMode
{
	AEFILLMODE_WIREFRAME	= 2,
	AEFILLMODE_SOLID		= 3
};

/// \brief
///   Enum that defines a simple render order of a technique, the values map to unique bits
enum AEPassType
{
	AEPASSTYPE_UNDEFINED			= 0,
	AEPASSTYPE_PRIMARYOPAQUEPASS	= 1, ///< gets rendered at the beginning of the intial pass, usually used to render opaque geometry
	AEPASSTYPE_SECONDARYOPAQUEPASS	= 4, ///< gets rendered at the end of the inital pass, usually used to do special effects like stencil operations
	AEPASSTYPE_TRANSPARENTPASS		= 2 ///< gets rendered in the transparent pass, use to render transparent geometry
};

/// \brief
///   Enumeration for supported static lighting methods used for materials
enum AELightingMethod
{
	AELIGHTING_FULLBRIGHT	= 0,
	AELIGHTING_LIGHTMAPPING = 1,
	AELIGHTING_LIGHTGRID	= 2,
	AELIGHTING_DYNAMIC_ONLY = 3
};

// Vertex format flags
#define AEVERTEXDESC_FORMAT_FLOAT        0x1000
#define AEVERTEXDESC_FORMAT_FLOAT2       0x2000
#define AEVERTEXDESC_FORMAT_FLOAT3       0x3000
#define AEVERTEXDESC_FORMAT_FLOAT4       0x4000
#define AEVERTEXDESC_FORMAT_BYTE4N       0x5000
#define AEVERTEXDESC_FORMAT_SHORT2N      0x6000
#define AEVERTEXDESC_FORMAT_SHORT4N      0x7000
#define AEVERTEXDESC_FORMAT_HALF2        0x8000
#define AEVERTEXDESC_FORMAT_HALF4        0x9000
#define AEVERTEXDESC_FORMAT_USHORT2N     0xA000
#define AEVERTEXDESC_FORMAT_USHORT4N     0xB000
#define AEVERTEXDESC_FORMAT_BYTE4        0xC000
#define AEVERTEXDESC_FORMAT_SHORT2       0xD000
#define AEVERTEXDESC_FORMAT_SHORT4       0xE000
#define AEVERTEXDESC_FORMAT_UBYTE4N      AEVERTEXDESC_FORMAT_BYTE4N


#define AEVERTEXDESC_FORMAT_MASK         0xF000
#define AEVERTEXDESC_OFFSET_MASK         0x0FFF

#define AEVERTEXDESC_FORMATOF(val)      ((val)&AEVERTEXDESC_FORMAT_MASK)
#define AEVERTEXDESC_OFFSETOF(val)      ((val)&AEVERTEXDESC_OFFSET_MASK)
#define AEVERTEXDESC_FORMATINDEX(val)   ((val)>>12)

#define AEVERTEXSTREAM_POSITION        (1 <<  0)
#define AEVERTEXSTREAM_NORMAL          (1 <<  1)
#define AEVERTEXSTREAM_COLOR           (1 <<  2)
#define AEVERTEXSTREAM_SECONDARYCOLOR  (1 <<  3)
#define AEVERTEXSTREAM_TEX0            (1 <<  4)
#define AEVERTEXSTREAM_TEX1            (1 <<  5)
#define AEVERTEXSTREAM_TEX2            (1 <<  6)
#define AEVERTEXSTREAM_TEX3            (1 <<  7)
#define AEVERTEXSTREAM_TEX4            (1 <<  8)
#define AEVERTEXSTREAM_TEX5            (1 <<  9)
#define AEVERTEXSTREAM_TEX6            (1 << 10)
#define AEVERTEXSTREAM_TEX7            (1 << 11)
#define AEVERTEXSTREAM_TEX8            (1 << 12)
#define AEVERTEXSTREAM_TEX9            (1 << 13)
#define AEVERTEXSTREAM_TEX10           (1 << 14)
#define AEVERTEXSTREAM_TEX11           (1 << 15)
#define AEVERTEXSTREAM_TEX12           (1 << 16)
#define AEVERTEXSTREAM_TEX13           (1 << 17)
#define AEVERTEXSTREAM_TEX14           (1 << 18)
#define AEVERTEXSTREAM_TEX15           (1 << 19)

#define AEVERTEXSTREAM_BONEINDEX       AEVERTEXSTREAM_TEX3
#define AEVERTEXSTREAM_BONEWEIGHT      AEVERTEXSTREAM_TEX4

#define AEVERTEXSTREAM_INDEXBUFFER     0x10000000

#define AEVERTEXSTREAM_TANGENT         AEVERTEXSTREAM_TEX2

#define AEVERTEXSTREAM_ALL             0xFFFFFFFF
#define AEVERTEXSTREAM_TEX_MASK        0x000FFFF0
#define AEVERTEXSTREAM_FIRST_TEX_BIT   4
#define AEVERTEXSTREAM_VERTEXRELEVANT  (AEVERTEXSTREAM_ALL & (~AEVERTEXSTREAM_INDEXBUFFER))

#define AEMAX_MESHBUFFER_TEXCOORDS      16

#define AESHADER_RASTERIZERSTATEBIT_FRONTCCW     AESETBIT(0)
#define AESHADER_RASTERIZERSTATEBIT_NODEPTHCLIP  AESETBIT(1)
#define AESHADER_RASTERIZERSTATEBIT_SCISSORTEST  AESETBIT(2)
#define AESHADER_RASTERIZERSTATEBIT_MULTISAMPLE  AESETBIT(3)

// Posizioni di default per gli stream
#define AESHADER_VERTEXPOSITION_INDEX			0
#define AESHADER_VERTEXCOLOR_INDEX				2

// Errori
#define AE_INVALIDSHADERSTAGE	0x100001
#define AE_SHADERNOTFOUND		0x100002
#define AE_SHADERCOMPILEERROR	0x100003
#define AE_SHADERLINKERROR		0x100004

#endif // _AESHADERSINCLUDE_H_
